#include "StdAfx.h"
#include "LockNChaseMachine.h"

#define Decrypt(dd)	((dd & 0x9F) | ((dd & 0x20) << 1) | ((dd & 0x40) >> 1))

CLockNChaseMachine::CLockNChaseMachine()
{
}

CLockNChaseMachine::~CLockNChaseMachine()
{
}

int CLockNChaseMachine::Init()
{
CBurgerTimeMachine::Init();
MainCPU->SetUser(this);
SoundCPU->SetUser(this);
MainCPU->SetRead(ReadMainCPU);
MainCPU->SetWrite(WriteMainCPU);
MainCPU->SetOp(OpMainCPU);
return(0);
}

void CLockNChaseMachine::Reset()
{
int n;

CBurgerTimeMachine::Reset();
for(n=0;n<0x10000;n++)
	NewROM[n] = Decrypt(MainROM[n]);
for(n=0;n<0x10;n++)
	WritePalette(n,~PROM[n]);
SoundNMIEnable = 1;
Bank = 1;
}

void CLockNChaseMachine::Poll()
{
/*u32 n;

Input->Poll();
n = Input->Get();
Input1 = Input2 = Input3 = 0;
if(n & I_UP)		Input1 |= 4;
if(n & I_DOWN)		Input1 |= 8;
if(n & I_LEFT)		Input1 |= 2;
if(n & I_RIGHT)	Input1 |= 1;
if(n & I_B1)		Input1 |= 0x10;
if(n & I_START1)	Input3 |= 0x01;
if(n & I_START2)	Input3 |= 0x02;
if(n & I_COIN1)	Input3 |= 0x40;
if(n & I_COIN2)	Input3 |= 0x80;
if(Input3 & 0xC0)
	MainCPU->NMI();
Input1 = ~Input1;
Input2 = ~Input2;
Input3 = ~Input3;
n = Input->GetDip();
Dip1 = (u8)n & 0x7F;
Dip2 = (u8)(n >> 8);*/
}

void CLockNChaseMachine::Frame()
{
do
	{
	if(Scanline < 256 && (Scanline & 0xF) == 0)
		{
		if(VideoControl & 8)					//lnc irq control
			SoundCPU->NMI();
		}
	Line(97,33,0);
	} while(Scanline != 0);
}

void CLockNChaseMachine::SaveState(CState *s)
{
CBurgerTimeMachine::SaveState(s);
s->Write8(SoundNMIEnable);
s->Write8(Bank);
s->Write(RAM,0x3C00);
s->Write(BGRAM,0x200);
}

void CLockNChaseMachine::LoadState(CState *s)
{
CBurgerTimeMachine::LoadState(s);
SoundNMIEnable = s->Read8();
Bank = s->Read8();
s->Read(RAM,0x3C00);
s->Read(BGRAM,0x200);
}

void CLockNChaseMachine::RenderScreen(u8 *dest,int pitch)
{
memset(dest,0,256*pitch);
RenderChars(dest,pitch);
RenderSprites(dest,pitch);
}

u8 CLockNChaseMachine::OpMainCPU(void *user,u32 addr)
{
CLockNChaseMachine *M = (CLockNChaseMachine*)user;

return(M->NewROM[addr]);
}

u8 CLockNChaseMachine::ReadMainCPU(void *user,u32 addr)
{
CLockNChaseMachine *M = (CLockNChaseMachine*)user;

if(addr < 0x3C00)
	return(M->RAM[addr]);
if(addr >= 0xC000)
	return(M->MainROM[addr]);
switch(addr & 0xFC00)
	{
	case 0x3C00:
		return(M->VideoRAM[addr & 0x3FF]);
	case 0x7C00:
		addr &= 0x3FF;
		return(M->VideoRAM[MirrorRAMAddr(addr)]);
	case 0x8000:
		switch(addr)
			{
			case 0x8000:	return((M->Dip[0] & 0x7F) | M->VBlank);
			case 0x8001:	return(M->Dip[1]);
			}
		break;
	case 0x9000:
		switch(addr)
			{
			case 0x9000:	return(M->InputData[0]);
			case 0x9001:	return(M->InputData[1]);
			case 0x9002:	return(M->InputData[2]);
			}
		break;
	case 0xB000:
		if(addr < 0xB200)
			return(M->BGRAM[addr & 0x1FF]);
		break;
	}
message("unhandled read (main cpu, addr $%04X)\n",addr);
return(0);
}

void CLockNChaseMachine::WriteMainCPU(void *user,u32 addr,u8 data)
{
CLockNChaseMachine *M = (CLockNChaseMachine*)user;

if(addr < 0x3C00)
	{
	M->RAM[addr] = data;
	return;
	}
switch(addr & 0xFC00)
	{
	case 0x3C00:
		addr &= 0x3FF;
		M->VideoRAM[addr] = data;
		M->ColorRAM[addr] = M->Bank;
		return;
	case 0x7C00:
		addr &= 0x3FF;
		M->VideoRAM[MirrorRAMAddr(addr)] = data;
		M->ColorRAM[MirrorRAMAddr(addr)] = M->Bank;
		return;
	case 0x8000:
	case 0x9000:
		switch(addr)
			{
			case 0x8000:
			case 0x9000:
				return;
			case 0x8001:
				M->SoundNMIEnable = data & 8;
				M->VideoControl = data;
				return;
			case 0x9002:
				M->WriteSoundControl(data);
				return;
			case 0x8003:
				M->Bank = data;
				return;
			}
		break;
	case 0xB000:
		if(addr < 0xB200)
			{
			M->BGRAM[addr & 0x1FF] = data;
			return;
			}
		break;
	}
message("unhandled write (main cpu, addr $%04X = $%02X)\n",addr,data);
}
